#include<iostream>
#include<string>
#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
#include<vector>
#include<cassert>
using namespace std;

class ThreadData
{
public:
    int number;
    pthread_t tid;
    char namebuff[64];
};

class ThreadReturn
{
public:
    int exit_code ;
    int exit_result ;
};

//1.start_routine，现在是被几个线程执行呢？10，这个函数现在是什么状态？重入状态
//2.该函数是可重入函数吗？是的！(不考虑打印)
//3，在函数内定义的变量，都叫做局部变量，在多线程情况下，也没有问题--其实每一个线程都有自己独立的栈结构-今天依旧适用
void *start_routine(void *args)
{
    //测试如果一个线程出现了问题会影响，其他进程吗？会！
    //出错会发送信号，信号是发给进程的！！
    // string name = static_cast<const char* >(args);//安全的进行强制类型转换
    //ThreadData *td = static_cast<ThreadData* >(args);//安全的进行强制类型转换
    ThreadData* td = static_cast<ThreadData*>(args);
    int cnt =10;        
    while(cnt)
    {
        // cout<<"cnt: "<<cnt<<"  &cnt : "<<&cnt<<endl;
        // cnt--;
        // sleep(1);
        // pthread_exit(nullptr);
 
        cout<<"new thread create success , name: "<<td->namebuff<<"cnt:"<<cnt--<<endl;
        sleep(1);
        // int *p =nullptr;
        // *p = 0;//出错崩溃

    }
    // cout<<endl;
    // delete td;
    // ThreadReturn * tr = new ThreadReturn();
    // tr->exit_code = 1;
    // tr->exit_result = 106;
// ThreadReturntr;//在栈上开辟的空间return·&tr;
    //return (void*)tr;//这时的tr是右值，(void*)tr 是一个 强制类型转换表达式，它的结果是一个 右值（因为转换后的 void* 临时结果没有名字）。
}

int main()
{
    //创建多个进程的方法
#define NUM 10
    vector<ThreadData*> threads;
    for(int i = 1 ; i <= NUM;i++)
    {
        ThreadData *td = new ThreadData();
        td->number = i; 
        snprintf(td->namebuff,sizeof(td->namebuff),"%s:%d","thread",i);
        pthread_create(&td->tid,nullptr,start_routine,td);
        threads.push_back(td);
    }

    // for(auto &iter: threads)
    // {
    //     cout<<"create thread:"<<iter->tid<<":"<<iter->namebuff<<"success"<<endl;
    // }
    sleep(5);
    for(int i = 0 ;i <5 ; i++)//进行进程取消
    {
        pthread_cancel(threads[i]->tid);
        cout<<"cancel success:"<<threads[i]->number<<endl;
    }
    for(auto &iter: threads)//进行进程等待
    {
        ThreadReturn* ret = nullptr;
        //？：为什么没有见到，线程退出的时候，对应的退出信号？？？线程出异常，收到信号，整个进程都会退出！
        //pthread_join：默认就认为函数会调用成功！不考虑异常问题，异常问题是你进程该考虑的问题！
        int n = pthread_join(iter->tid,(void**)&ret);//成功返回0
        assert(n == 0);
        // uintptr_t result = reinterpret_cast<uintptr_t>(ret);
        // cout <<"number:"<<"join:"<<iter->namebuff <<"success number:"<<static_cast<int>(result)  << endl;
        cout<<"cancel return:"<<(long long)ret<<endl;
        delete iter;
    }


    //cout <<"main thread quit" << endl;
    while(true)
    {

        cout<<"new thread create success , name : main thread"<<endl;
        sleep(1);
    }
    return 0;
}
